---
title: Create React App (CRA)에서 마이그레이션
description: 기존 Create React App 프로젝트를 Astro로 마이그레이션하기 위한 팁
type: migration
stub: true
framework: Create React App
i18nReady: true
---

import AstroJSXTabs from '~/components/tabs/AstroJSXTabs.astro';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
import { FileTree } from '@astrojs/starlight/components';
import ReadMore from '~/components/ReadMore.astro';
import Badge from '~/components/Badge.astro';

Astro의 [React integration](/ko/guides/integrations-guide/react/)은 Create React App (CRA)와 같은 전체 React 앱을 포함하여 [Astro 컴포넌트 내부에서 React 컴포넌트를 사용](/ko/guides/framework-components/)하기 위한 지원을 제공합니다!

```astro title="src/pages/index.astro"
---
// 루트 App 컴포넌트 가져오기
import App from '../cra-project/App.jsx';
---
<!-- 클라이언트 지시어를 사용하여 앱 로드 -->
<App client:load />
```

React Router를 사용하여 [Astro로 단일 페이지 애플리케이션 (SPA)을 구축 하는 방법](https://logsnag.com/blog/react-spa-with-astro) <Badge variant="accent">External</Badge> 을 알아보세요.

React 통합이 설치된 Astro 프로젝트에 직접 추가하면 많은 앱이 전체 React 앱으로 "작동"합니다. 이는 프로젝트를 즉시 시작하고 실행하고 Astro로 마이그레이션하는 동안 앱 기능을 유지할 수 있는 좋은 방법입니다.

시간이 지남에 따라 구조를 하나씩 `.astro` 및 `.jsx` 컴포넌트의 조합으로 변환할 수 있습니다. 아마도 여러분이 생각하는 것보다 더 적은 수의 React 컴포넌트가 필요하다는 것을 알게 될 것입니다!

다음은 시작하는 데 도움이 되는 몇 가지 주요 개념과 마이그레이션 전략입니다. 계속 진행하려면 나머지 문서와 [Discord 커뮤니티](https://astro.build/chat)를 활용하세요!

## CRA와 Astro의 주요 유사점

- [`.astro` 파일의 구문은 JSX와 유사합니다](/ko/basics/astro-syntax/#astro와-jsx의-차이점). Astro를 쓰는 것은 친숙하게 느껴질 것입니다.

- Astro는 파일 기반 라우팅을 사용하며 [특별히 명명된 페이지가 동적 경로를 생성하도록 허용합니다](/ko/guides/routing/#동적-경로).

- Astro는 [컴포넌트 기반](/ko/basics/astro-components/)이며 마이그레이션 전후의 마크업 구조는 유사합니다.

- Astro에는 [React, Preact, Solid에 대한 공식 통합](/ko/guides/integrations-guide/react/)이 있으므로 기존 JSX 컴포넌트를 사용할 수 있습니다. Astro에서 이러한 파일은 **반드시** `.jsx` 또는 `.tsx` 확장자를 가져야 합니다.

- Astro는 React 라이브러리를 포함하여 [NPM 패키지 설치](/ko/guides/imports/#npm-패키지)를 지원합니다. 기존 종속성 중 상당수가 Astro에서 작동합니다.

## CRA와 Astro의 주요 차이점

Astro에서 CRA 사이트를 다시 빌드하면 몇 가지 중요한 차이점을 발견할 수 있습니다.

- CRA는 `index.js`를 프로젝트 루트로 사용하는 단일 페이지 애플리케이션입니다. Astro는 다중 페이지 사이트이고 `index.astro`는 홈 페이지입니다.

- [`.astro` 컴포넌트](/ko/basics/astro-components/)는 페이지 템플릿을 반환하는 내보낸 함수로 작성되지 않습니다. 대신, 코드를 JavaScript용 "코드 펜스"와 생성한 HTML 전용 본문으로 분할합니다.

- [콘텐츠 중심](/ko/concepts/why-astro/#콘텐츠-중심): Astro는 콘텐츠를 선보이고 필요할 때만 상호 작용을 선택할 수 있도록 설계되었습니다. 기존 CRA 앱은 높은 클라이언트 측 상호 작용을 위해 빌드될 수 있으며 대시보드와 같은 `.astro` 컴포넌트를 사용하여 복제하기가 더 어려운 항목을 포함하려면 고급 Astro 기술이 필요할 수 있습니다.

## Astro에 CRA 추가

기존 앱은 새로운 Astro 프로젝트 내에서 직접 렌더링될 수 있으며, 대개 앱 코드를 변경하지 않아도 됩니다.

### 새 Astro 프로젝트 만들기

패키지 관리자의 `create astro` 명령을 사용하여 Astro의 CLI 마법사를 시작하고 새로운 "empty" Astro 프로젝트를 선택하세요.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm create astro@latest
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm create astro@latest
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn create astro@latest
  ```
  </Fragment>
</PackageManagerTabs>

### 통합 및 종속성 추가

패키지 관리자의 `astro add` 명령을 사용하여 React 통합을 추가합니다. 앱에서 Tailwind 또는 MDX를 사용하는 경우 동일한 명령을 사용하여 여러 Astro 통합을 추가할 수 있습니다.

<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npx astro add react
  npx astro add react tailwind mdx
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm astro add react
  pnpm astro add react tailwind mdx
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn astro add react
  yarn astro add react tailwind mdx
  ```
  </Fragment>
</PackageManagerTabs>

CRA에 종속성이 필요한 경우 (예: NPM 패키지), 명령줄을 사용하여 개별적으로 설치하거나 새 Astro 프로젝트의 `package.json` 파일에 수동으로 추가한 다음 install 명령을 실행하여 설치하세요. 전부는 아니지만 많은 React 종속성이 Astro에서 작동한다는 점에 유의하세요.

### 기존 앱 파일 추가

기존 Create React App (CRA) 프로젝트 소스 파일 및 폴더 (예: `components`, `hooks`, `styles` 등)를 `src/` 내부의 새 폴더에 복사하여 앱이 계속 작동할 수 있도록 파일 구조를 유지합니다. 모든 `.js` 파일 확장자의 이름을 `.jsx` 또는 `.tsx`로 바꿔야 합니다.

구성 파일을 포함하지 마세요. Astro의 자체 `astro.config.mjs`, `package.json`, `tsconfig.json` 파일을 사용합니다.

앱의 `public/` 폴더 내용 (예: 정적 자산)을 Astro의 `public/` 폴더로 이동하세요.

<FileTree>
- public/
  - logo.png
  - favicon.ico
  - ...
- src/
  - cra-project/
    - App.jsx
    - ...
  - pages/
    - index.astro
- astro.config.mjs
- package.json
- tsconfig.json
</FileTree>

### 앱 렌더링

`index.astro`의 프런트매터 섹션에서 앱의 루트 컴포넌트를 가져온 다음 페이지 템플릿에서 `<App />` 컴포넌트를 렌더링합니다.

```astro title="src/pages/index.astro"
---
import App from '../cra-project/App.jsx';
---
<App client:load />
```

:::note[클라이언트 지시어]
앱에 상호작용을 위해서는 [클라이언트 지시어](/ko/reference/directives-reference/#클라이언트-지시어)가 필요합니다. Astro는 클라이언트 측 JavaScript를 선택할 때까지 React 앱을 정적 HTML로 렌더링합니다.

앱이 서버에서 즉시 로드되도록 하려면 `client:load`를 사용하고, 서버 측 렌더링을 건너뛰고 앱을 완전히 클라이언트 측에서 실행하려면 `client:only="react"`를 사용하세요.
:::

자세한 내용과 사용 가능한 옵션은 [Astro 구성](/ko/guides/configuring-astro/) 가이드를 참조하세요.

## CRA를 Astro로 전환

[기존 앱을 Astro에 추가](#astro에-cra-추가)한 후 앱 자체를 Astro로 변환하고 싶을 것입니다!

[기본 구조에 Astro HTML 템플릿 컴포넌트를 사용](/ko/basics/astro-components/)하여 유사한 컴포넌트 기반 디자인을 복제하는 동시에 상호 작용을 위한 개별 React 컴포넌트 (전체 앱일 수도 있음)를 가져오고 포함합니다.

모든 마이그레이션은 다르게 보이며 작업 중인 앱을 중단하지 않고 점진적으로 수행할 수 있습니다. 시간이 지남에 따라 점점 더 많은 앱이 Astro 컴포넌트로 구동되도록 개별 부분을 원하는 속도로 변환하세요.

React 앱을 변환할 때 [Astro 컴포넌트로 다시 작성할](#jsx-파일을-astro-파일로-변환) React 컴포넌트를 결정하게 됩니다. 유일한 제한 사항은 Astro 컴포넌트가 React 컴포넌트를 가져올 수 있다는 것입니다. 그러나 React 컴포넌트는 다른 React 컴포넌트만 가져와야 합니다.

```astro title="src/pages/static-components.astro" ins={2,7}
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<html>
  <body>
    <h1>Use React components directly in Astro!</h1>
    <MyReactComponent />
  </body>
</html>
```

Astro 컴포넌트를 React 컴포넌트로 가져오는 대신 단일 Astro 컴포넌트 내에 React 컴포넌트를 중첩할 수 있습니다.

```astro title="src/pages/nested-components.astro" {2,3,5,8,10}
---
import MyReactSidebar from '../components/MyReactSidebar.jsx';
import MyReactButton from '../components/MyReactButton.jsx';
---
<MyReactSidebar>
  <p>Here is a sidebar with some text and a button.</p>
  <div slot="actions">
    <MyReactButton client:idle />
  </div>
</MyReactSidebar>
```

CRA를 Astro 프로젝트로 재구성하기 전에 [Astro 아일랜드](/ko/concepts/islands/) 및 [Astro 컴포넌트](/ko/basics/astro-components/)에 대해 알아보는 것이 도움이 될 수 있습니다.

### 비교: JSX vs Astro

다음 CRA 컴포넌트와 해당 Astro 컴포넌트를 비교해 보세요.

<AstroJSXTabs>
  <Fragment slot="jsx">
    ```jsx title="StarCount.jsx"
    import React, { useState, useEffect } from 'react';
import Header from './Header';
import Footer from './Footer';

const Component = () => {
    const [stars, setStars] = useState(0);
    const [message, setMessage] = useState('');

    useEffect(() => {
        const fetchData = async () => {
            const res = await fetch('https://api.github.com/repos/withastro/astro');
            const json = await res.json();

            setStars(json.stargazers_count || 0);
            setMessage(json.message);
        };

        fetchData();
    }, []);

    return (
        <>
            <Header />
            <p style={{
                backgroundColor: `#f4f4f4`,
                padding: `1em 1.5em`,
                textAlign: `center`,
                marginBottom: `1em`
            }}>Astro has {stars} 🧑‍🚀</p>
            <Footer />
        </>
    )
};

export default Component;
    ```
  </Fragment>
  <Fragment slot="astro">
    ```astro title="StarCount.astro"
    ---
    import Header from './Header.astro';
    import Footer from './Footer.astro';
    import './layout.css';
    const res = await fetch('https://api.github.com/repos/withastro/astro')
    const json = await res.json();
    const message = json.message;
    const stars = json.stargazers_count || 0;
    ---
    <Header />
    <p class="banner">Astro has {stars} 🧑‍🚀</p>
    <Footer />
    <style>
      .banner {
        background-color: #f4f4f4; 
        padding: 1em 1.5em;
        text-align: center;
        margin-bottom: 1em;
      }
    <style>
    ```
  </Fragment>
</AstroJSXTabs>

### JSX 파일을 `.astro` 파일로 변환

다음은 CRA `.js` 컴포넌트를 `.astro` 컴포넌트로 변환하기 위한 몇 가지 팁입니다.

1. 기존 CRA 컴포넌트 함수의 반환된 JSX를 HTML 템플릿의 기초로 사용합니다.

2. [CRA 또는 JSX 구문을 Astro로](#참조-cra-구문을-astro로-변환) 또는 HTML 웹 표준으로 변경합니다. 예를 들어 여기에는 `{children}` 및 `className`이 포함됩니다.

3. import 구문을 포함하여 필요한 JavaScript를 ["코드 펜스" (`---`)](/ko/basics/astro-components/#컴포넌트-스크립트)로 이동합니다. 참고: [조건부 콘텐츠 렌더링](/ko/basics/astro-syntax/#동적-html)을 위한 JavaScript는 Astro에서 직접 HTML 템플릿 내에 작성되는 경우가 많습니다.

4. 이전에 CRA 함수에 전달된 추가 props에 액세스하려면 [`Astro.props`](/ko/reference/api-reference/#astroprops)를 사용하세요.

5. 가져온 컴포넌트도 Astro로 변환해야 하는지 여부를 결정합니다. 지금 당장 또는 영원히 React 컴포넌트로 유지할 수 있습니다. 하지만 결국에는 `.astro` 컴포넌트로 변환하고 싶을 수도 있습니다. 특히 대화형이 필요하지 않은 경우에는 더욱 그렇습니다!

6. `useEffect()`를 import 문으로 바꾸거나 [`Astro.glob()`](/ko/reference/api-reference/#astroglob)을 사용하여 로컬 파일을 쿼리합니다. 외부 데이터를 가져오려면 `fetch()`를 사용하세요.

### 테스트 마이그레이션

Astro는 원시 HTML을 출력하므로 빌드 단계의 출력을 사용하여 end-to-end 테스트를 작성하는 것이 가능합니다. 이전에 작성된 end-to-end 테스트는 CRA 사이트의 마크업과 일치할 수 있는 경우 즉시 작동할 수 있습니다. Jest 및 React Testing Library와 같은 테스트 라이브러리를 Astro에서 가져와서 React 컴포넌트를 테스트하는 데 사용할 수 있습니다.

자세한 내용은 Astro의 [테스트 가이드](/ko/guides/testing/)를 참조하세요.

## 참조: CRA 구문을 Astro로 변환

### CRA Imports 변환

상대 파일 경로를 정확하게 참조하도록 모든 [파일 가져오기](/ko/guides/imports/)를 업데이트하세요. 이는 [가져오기 별칭](/ko/guides/typescript/#가져오기-별칭)을 사용하거나 상대 경로 전체를 작성하여 수행할 수 있습니다.

`.astro` 및 기타 여러 파일 형식은 전체 파일 확장자를 사용하여 가져와야 합니다.

```astro title="src/pages/authors/Fred.astro"
---
import Card from '../../components/Card.astro';
---
<Card />
```

### CRA Children Props 변환

`{children}`의 모든 인스턴스를 Astro `<slot />`으로 변환하세요. Astro는 `{children}`을 함수 prop으로 받을 필요가 없으며 자동으로 `<slot />`에 하위 콘텐츠를 렌더링합니다.

```astro title="src/components/MyComponent.astro" del={3-9} ins={11-13}
---
---
export default function MyComponent(props) { 
    return (
      <div>
        {props.children}
      </div>
    );  
}

<div>
  <slot />
</div>
```

여러 children 집합을 전달하는 React 컴포넌트는 [명명된 슬롯](/ko/basics/astro-components/#명명된-슬롯)을 사용하여 Astro 컴포넌트로 마이그레이션될 수 있습니다.

[Astro의 특정 `<slot />` 사용법](/ko/basics/astro-components/#슬롯)에 대해 자세히 알아보세요.

### CRA 데이터 페칭 변환

Create React App 컴포넌트에서 데이터를 가져오는 것은 약간의 차이점을 제외하고 Astro와 유사합니다.

프로젝트 소스에 있는 다른 파일의 데이터에 액세스하려면 `Astro.glob()` 또는 `getCollection()`/`getEntryBySlug()`에 대한 사이드 이펙트 후크 (`useEffect`)의 인스턴스를 제거해야 합니다.

[원격 데이터를 가져오려면](/ko/guides/data-fetching/) `fetch()`를 사용하세요.

이러한 데이터 요청은 Astro 컴포넌트의 프런트매터에서 이루어지며 top-level await을 사용합니다.

```astro title="src/pages/index.astro"
---
import { getCollection } from 'astro:content';

// 모든 `src/content/blog/` 항목 가져오기
const allBlogPosts = await getCollection('blog');

// 모든 `src/pages/posts/` 항목을 가져오기
const allPosts = await Astro.glob('../pages/posts/*.md');

// 원격 데이터 가져오기
const response = await fetch('https://randomuser.me/api/');
const data = await response.json();
const randomUser = data.results[0];
---
```

[`Astro.glob()`을 사용한 로컬 파일 가져오기](/ko/guides/imports/#astroglob), [Collections API를 사용한 쿼리](/ko/guides/content-collections/#컬렉션-쿼리) 또는 [원격 데이터 가져오기](/ko/guides/data-fetching/)에 대해 자세히 알아보세요.

### CRA 스타일링 변환

[CSS-in-JS 라이브러리](https://github.com/withastro/astro/issues/4432) (예: styled-components)를 Astro에서 사용 가능한 다른 CSS 옵션으로 바꿔야 할 수도 있습니다.

필요한 경우 인라인 스타일 객체 (`style={{ fontWeight: "bold" }}`)를 인라인 HTML 스타일 속성(`style="font-weight:bold;"`)으로 변환합니다. 또는 범위가 지정된 CSS 스타일에는 [Astro `<style>` 태그](/ko/guides/styling/#astro에서-스타일링하기)를 사용하세요.

```astro title="src/components/Card.astro" del={1} ins={2}
<div style={{backgroundColor: `#f4f4f4`, padding: `1em`}}>{message}</div>
<div style="background-color: #f4f4f4; padding: 1em;">{message}</div>
```

Tailwind는 [Tailwind 통합](/ko/guides/integrations-guide/tailwind/) 설치 후 지원됩니다. 기존 Tailwind 코드를 변경할 필요가 없습니다!

[Astro에서의 스타일링](/ko/guides/styling/)에 대해 자세히 알아보세요.

## 문제 해결

여러분의 CRA가 Astro에서 "그냥 작동"할 수도 있습니다! 그러나 기존 앱의 기능 및/또는 스타일을 복제하려면 약간의 조정이 필요할 수 있습니다.

이 문서에서 답변을 찾을 수 없다면 [Astro Discord](https://astro.build/chat)를 방문하여 support 포럼에 질문하세요!
